package com.study02.config;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.stereotype.Component;

@Component
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authorizeHttpRequests ->
                        authorizeHttpRequests.requestMatchers("/admin/api").hasRole("admin")// 角色必须是admin
                                .requestMatchers("/user/api").hasAnyRole("admin","user")  //角色是admin或者user都可以
                                .requestMatchers("/app/api").permitAll()
                                .requestMatchers("/login").permitAll()
                        .anyRequest().authenticated()
        );

        http.formLogin(forlogin ->
                        forlogin.loginPage("/login").permitAll()
                                .loginProcessingUrl("/login")
                                .defaultSuccessUrl("/index")
        );
        http.exceptionHandling(e->e.accessDeniedPage("/noAuth"));   //异常处理页面 [实际上不合理的,我们应该捕获异常信息,通过异常类型来判断是什么异常]

        http.csrf(Customizer.withDefaults()); //跨域漏洞防御:关闭
        http.cors(Customizer.withDefaults()); //跨域拦截关闭

        //退出
        http.logout(logout -> logout.invalidateHttpSession(true)); //退出后删除session
        return http.build();
    }

    //将用户信息配置到代码中
    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
        UserDetails user = User.withUsername("user")
                .password("123456")
                .roles("user")
                .build();
        UserDetails admin = User.withUsername("admin")
                .password("123456")
                .roles("admin", "user")
                .build();
        return new InMemoryUserDetailsManager(user, admin);
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

}
